home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / packer / unpacker / unpacker.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  7KB  |  318 lines

  1. ////
  2. //  UnPacker.c v1.2, 1993-09-22
  3. //  Utility for extracting archives from the WB.
  4. //
  5. //  This code is Copyright © 1993 Erik Sagalara.
  6. //  I supplied it as an example of programming
  7. //  Appicons, Tooltypes and other V37+ stuff.
  8. //
  9. //  You should be able to compile it easily with
  10. //  SASC, and with some tweaking with GCC.  
  11. ///
  12.  
  13. #include <intuition/intuition.h>
  14. #include <workbench/workbench.h>
  15. #include <workbench/startup.h>
  16. #include <dos/dos.h>
  17. #include <dos/dosextens.h>
  18. #include <clib/intuition_protos.h>
  19. #include <clib/icon_protos.h>
  20. #include <clib/wb_protos.h>
  21. #include <clib/dos_protos.h>
  22.  
  23. #include <string.h>
  24. #include <stdio.h>
  25.  
  26. #ifdef LATTICE
  27. int CXBRK(void) { return (0); }
  28. int chkabort(void) { return (0); }
  29. #endif
  30.  
  31. struct IntuitionBase* IntuitionBase;
  32. struct DosBase* DosBase;
  33. struct Library* WorkbenchBase;
  34. struct Library* IconBase;
  35.  
  36.  
  37. // Global variables
  38.  
  39. BPTR OldDir=NULL, DestDir=NULL;
  40. UBYTE* version = "$VER: UnPacker 1.2; 93-09-22";
  41. UBYTE* OK = "OK!";
  42. UBYTE *alertMsg =
  43.     "\x00\x90\x14" "UnPacker requires AmigaDos 2.04 or higher!" "\x00\x01"
  44.     "\x00\x20\x26" "Left=OK!" "\x00\x01"
  45.     "\x02\x15\x26" "Right=OK!" "\x00";
  46.  
  47. struct MsgPort* myport=NULL;
  48. struct AppIcon* appicon=NULL;
  49.  
  50. char* SuffixList[32];
  51. char* MethodList[32];
  52. UBYTE NumItems=0; 
  53.  
  54. // Local protos
  55.  
  56. void handletool (char*, char*, char*);
  57. void handlefile (BPTR, char*);
  58. int easyreq (char*, char*, char*, char*);
  59. void cleanexit (char*, int);
  60.  
  61.  
  62. ////
  63. //  Main
  64. ////
  65.  
  66. void main (int argc, char **argv)
  67. {
  68.     struct DiskObject* diskobj;
  69.     struct AppMessage* appmsg;
  70.     struct WBStartup* argmsg;
  71.     struct WBArg* wbarg;
  72.     char tlab[80], tval[80];
  73.     UBYTE i, j;
  74.     BOOL ok=TRUE;
  75.  
  76.     if (!(IntuitionBase = (struct IntuitionBase*) OpenLibrary("intuition.library", 0)))
  77.         cleanexit ("", 20);
  78.  
  79.     if (!(DosBase = (struct Library*) OpenLibrary("dos.library", 37)))
  80.         cleanexit ("", 20);
  81.  
  82.     if (!(WorkbenchBase = (struct Library*) OpenLibrary("workbench.library", 37)))
  83.         cleanexit ("", 20);
  84.  
  85.     if (!(IconBase = (struct Library*) OpenLibrary("icon.library", 37)))
  86.         cleanexit ("", 20);
  87.  
  88.     // CLI Startup if argc>0
  89.     if (argc)
  90.         cleanexit ("This program must be started\nfrom the workbench!", 10);
  91.  
  92.     // Otherwise wb startup
  93.     argmsg = (struct WBStartup*) argv;
  94.     wbarg = argmsg->sm_ArgList;
  95.  
  96.     if (wbarg->wa_Lock) {
  97.         OldDir = CurrentDir (wbarg->wa_Lock);
  98.         diskobj = GetDiskObject (wbarg->wa_Name);
  99.     }
  100.     else cleanexit ("Can't access the program icon!\n", 10);
  101.  
  102.     diskobj->do_Type = NULL;
  103.     diskobj->do_CurrentX = -2147483648L;
  104.     diskobj->do_CurrentY = -2147483648L;
  105.  
  106.     for (i=0; diskobj->do_ToolTypes[i] != NULL; i++) {
  107.         handletool (diskobj->do_ToolTypes[i], tlab, tval);
  108.         if (strlen (tlab) > 0) {
  109.             char* errstr="Error in tooltype entry: ";
  110.             j = strlen (tval);
  111.  
  112.             if (strcmp (tlab, "XPOS") == 0) {
  113.                 if (j > 0)
  114.                     diskobj->do_CurrentX = atol (tval);
  115.                 else
  116.                     easyreq (errstr, diskobj->do_ToolTypes[i], OK, OK);
  117.             }
  118.  
  119.             else if (strcmp (tlab, "YPOS") == 0) {
  120.                 if (j > 0)
  121.                     diskobj->do_CurrentY = atol (tval);
  122.                 else
  123.                     easyreq (errstr, diskobj->do_ToolTypes[i], OK, OK);
  124.             }
  125.  
  126.             else if (strcmp (tlab, "DESTDIR") == 0) {
  127.                 if (j > 0) {
  128.                     if (NULL == (DestDir = Lock (tval, ACCESS_READ)))
  129.                         cleanexit ("Can't lock to dest dir!", 10);
  130.                 }
  131.                 else
  132.                     easyreq (errstr, diskobj->do_ToolTypes[i], OK, OK);
  133.             }
  134.  
  135.             else if (strlen (tlab) <= 3) {
  136.                 if (j > 0 && NumItems < 32) {
  137.                     SuffixList[NumItems] = strdup (tlab);
  138.                     MethodList[NumItems] = strdup (tval);
  139.                     NumItems++;
  140.                 }
  141.                 else easyreq (errstr, diskobj->do_ToolTypes[i], OK, OK);
  142.             }
  143.         }
  144.     }    
  145.  
  146.     // ToolManager startup
  147.     if (argmsg->sm_NumArgs > 1) {
  148.         for (i=1; i<argmsg->sm_NumArgs; i++)
  149.             handlefile (argmsg->sm_ArgList[i].wa_Lock, argmsg->sm_ArgList[i].wa_Name);
  150.         cleanexit ("", 0);
  151.     }
  152.  
  153.     // Otherwise use appicon
  154.     if (!(myport = (struct MsgPort *) CreateMsgPort ()))
  155.         cleanexit ("Can't create message port!", 10);
  156.  
  157.     if (!(appicon = AddAppIconA (0L, 0L, "UnPacker", myport, NULL, diskobj, NULL)))
  158.         cleanexit ("Can't create appicon!", 10);
  159.  
  160.     while (ok) {
  161.         WaitPort (myport);
  162.  
  163.         while (appmsg = (struct AppMessage *) GetMsg (myport)) {
  164.             if (appmsg->am_NumArgs == 0) {
  165.                 if (easyreq ("UnPacker v1.2, 93-09-22.\nCopyright ©1993 Erik Sagalara.\n",
  166.                                  "This program is FreeWare!", "QUIT!", "Continue"))
  167.                     ok = FALSE;
  168.             }
  169.             else {
  170.                 UBYTE i;
  171.                 for (i=0; i<appmsg->am_NumArgs; i++)
  172.                     handlefile (appmsg->am_ArgList[i].wa_Lock, appmsg->am_ArgList[i].wa_Name);
  173.             }
  174.  
  175.             ReplyMsg ((struct Message *) appmsg);
  176.         }
  177.     }
  178.         
  179.     RemoveAppIcon (appicon);
  180.  
  181.     while (appmsg = (struct AppMessage *) GetMsg(myport))
  182.         ReplyMsg ((struct Message *) appmsg);
  183.  
  184.     FreeDiskObject (diskobj);
  185.     DeleteMsgPort (myport);
  186.  
  187.     cleanexit ("", 0);
  188. }
  189.  
  190.  
  191. ////
  192. //  Process a tooltype assignment string (XYZ=123)
  193. ////
  194.  
  195. void handletool (char* instr, char* label, char* value)
  196. {
  197.     UBYTE i, j, len;
  198.  
  199.     len = strlen(instr);
  200.  
  201.     for (i=0; (i<len) && (instr[i]!='='); i++) label[i] = toupper (instr[i]);
  202.  
  203.     label[i] = '\0';
  204.  
  205.     if (instr[i] != '=' && i >= len) {
  206.         value[0] = '\0';
  207.     }
  208.     else {
  209.         i++;
  210.         for (j=0; j+i<=len; j++) value[j] = instr[j+i];
  211.         value[j] = '\0';
  212.     }
  213. }    
  214.  
  215.  
  216. ////
  217. //  Process an archive file
  218. ////
  219.  
  220. void handlefile (BPTR lock, char* name)
  221. {
  222.     UBYTE i, j;
  223.     BOOL found=FALSE;
  224.     char *buf1,* buf2, *method1, *method2, suffix[4]="   ";
  225.  
  226.     for (i=strlen(name)-1; i>0 && (name[i] != '.'); i--);
  227.     if (name[i] != '.') goto err;
  228.  
  229.     if (strlen (&name[i+1]) > 3) goto err;
  230.     for (j=0; suffix[j]!='\0'; j++) suffix[j] = toupper(name[i+j+1]);
  231.  
  232.     for (i=0; i<NumItems && SuffixList[i]!=NULL; i++)
  233.         if (strcmp (suffix, SuffixList[i]) == 0) {
  234.             found = TRUE;
  235.             break;
  236.         }
  237.     if (!found) goto err;
  238.  
  239.     method1 = strdup (MethodList[i]);
  240.     for (j=0; j<strlen(method1) && method1[j]!='?'; j++);
  241.     if (method1[j]=='?') {
  242.         if (strlen (method1) > j)
  243.             method2 = strdup (&method1[j+1]);
  244.         else
  245.             method2 = strdup ("");
  246.         method1[j] = '\0';
  247.     }
  248.     else
  249.         method2 = strdup ("");
  250.  
  251.     buf2 = (char*) malloc (256);
  252.     NameFromLock (lock, buf2, 255);
  253.     AddPart (buf2, name, 255);
  254.     
  255.     buf1 = (char*) malloc (strlen(method1) + strlen(buf2) + strlen(method2) + 40);
  256.     sprintf (buf1, "%s \"%s\" %s >CON:0/25/640/150/UnPacking.../CLOSE/AUTO/WAIT",
  257.                 method1, buf2, method2);
  258.  
  259.     CurrentDir (DestDir);
  260.     system (buf1);
  261.  
  262.     free (buf1);
  263.     free (buf2);
  264.     free (method1);
  265.     free (method2);
  266.     return;
  267.     err: easyreq ("Unknown suffix for file:\n", name, OK, OK);
  268. }
  269.  
  270.  
  271. ////
  272. //  Easy requester
  273. ////
  274.  
  275. int easyreq (char* bodystr, char* extra, char* yesstr, char* nostr)
  276. {
  277.     static struct EasyStruct myES = {
  278.         sizeof(struct EasyStruct),
  279.         0,
  280.         "UnPacker requester:",
  281.         "%s%s",
  282.         "%s|%s",
  283.     };
  284.  
  285.     return (EasyRequest(NULL, &myES, NULL, bodystr, extra, yesstr, nostr));
  286. }
  287.  
  288.  
  289. ////
  290. //  Exits cleanly closing librarys and leaving a message
  291. ////
  292.  
  293. void cleanexit (char* exitstr, int stat)
  294. {
  295.     UBYTE i;
  296.  
  297.     if (stat)
  298.         if (stat == 20)
  299.             DisplayAlert(RECOVERY_ALERT, alertMsg, 52);
  300.         else
  301.             easyreq (exitstr, "", OK, OK);
  302.  
  303.     for (i=0; i<NumItems; i++) {
  304.         if (SuffixList[i]) free (SuffixList[i]);
  305.         if (MethodList[i]) free (MethodList[i]);
  306.     }
  307.  
  308.     if (DestDir) UnLock (DestDir);
  309.     if (OldDir) CurrentDir (OldDir);
  310.     
  311.     if (IntuitionBase) CloseLibrary (IntuitionBase);
  312.     if (WorkbenchBase) CloseLibrary (WorkbenchBase);
  313.     if (IconBase) CloseLibrary (IconBase);
  314.     if (DosBase) CloseLibrary (DosBase);
  315.  
  316.     exit (stat);
  317. }
  318.